package com.ruoyi.outpatient.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.outpatient.core.SecurityUtils;
import com.ruoyi.outpatient.domain.Comment;
import com.ruoyi.outpatient.domain.CommentVo;
import com.ruoyi.outpatient.domain.Reply;
import com.ruoyi.outpatient.mapper.ICommentMapper;
import com.ruoyi.outpatient.mapper.IReplyMapper;
import com.ruoyi.outpatient.service.ICommentService;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author 伟峰
 * @date 2022/4/30
 * @description:
 */
@Service
public class CommentServiceImpl implements ICommentService {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private SecurityUtils securityUtils;


    @Autowired
    private IReplyMapper replyMapper;

    @Autowired
    private ICommentMapper commentMapper;
    /**
     * 给评论进行点赞
     * @param blogId 分享id
     * @param commentId 评论id
     * @return true
     */
    @Override
    public AjaxResult likeComment( Long commentId) {

        //        1.获取点赞的登录用户
        Long loginPersonId = securityUtils.getLoginPersonId();

//        2.判断用户是否点赞过 (在comment中 看有没有该用户id) O(1)
        Boolean isMember = redisCache.isMemberSet("comment:likes:" + commentId,loginPersonId);


        if (BooleanUtils.isFalse(isMember)){

//            看键是否存在
            boolean exists = redisCache.exists("comment:likesPlusOne:" + commentId);

            if (exists==true){
//                说明set中的key没过期
                Long aLong = redisCache.setCacheIncrement("comment:likesPlusOne:" + commentId);

//            将 给用户点赞 放到set 表示点赞过
                if (aLong>-1){
                    redisCache.setCacheSets("comment:likes:" + commentId,loginPersonId);
                }


                //                最后统计下该用户所有点赞总数
                redisCache.setCacheHyperLogLog("person:viewTotal:"+loginPersonId);
                //        统计互动数（点赞+收藏+评论）
                redisCache.setCacheHyperLogLog("statistics:interaction:"+loginPersonId, UUID.randomUUID());
                return AjaxResult.success("评论点赞成功").put("likesSum",aLong);
            }

//                说明redis统计已经过期了,要去数据库拿
            long likesSum=commentMapper.selectCommentLikes(commentId);
//            将数据库更新到redis中 且要加一   设置15天后过期,然后定时任务在过期时刷新到数据库
            redisCache.setCacheObject("comment:likes:" + commentId,likesSum+1,15, TimeUnit.DAYS);



            //                最后统计下该用户所有点赞总数
            redisCache.setCacheHyperLogLog("person:viewTotal:"+loginPersonId);
            //        统计互动数（点赞+收藏+评论）
            redisCache.setCacheHyperLogLog("statistics:interaction:"+loginPersonId, UUID.randomUUID());
            return AjaxResult.success("评论进行点赞成功").put("likesSum",likesSum);

        }else {

            boolean exists = redisCache.exists("comment:likesPlusOne:" + commentId);
            if (exists==true){
//                说明set中的key没过期
                //            redis点赞数-1
                Long aLong = redisCache.setCacheDecrement("comment:likesPlusOne:" + commentId);

//            将给用户点赞放到set 表示点赞过
                if (aLong>-1){
                    redisCache.setRemove("comment:likes:" + commentId,loginPersonId);
                }
                return AjaxResult.success("取消点赞成功").put("likesSum",aLong);
            }

//                说明redis统计已经过期了,要去数据库拿
            long likesSum=commentMapper.selectCommentLikes(commentId);
//            将数据库更新到redis中且 减1     设置15天后过期,然后定时任务在过期时刷新到数据库
            redisCache.setCacheObject("comment:likes:" + commentId,likesSum-1,15,TimeUnit.DAYS);

            return AjaxResult.success("取消点赞成功").put("likesSum",likesSum);
        }
    }

    /**
     * 刷新更多的评论
     * @param blogId
     * @param createTime
     * @return
     */
    @Override
    public AjaxResult selectCommentList(Long blogId, Long createTime) {

        List<CommentVo> commentVos=new ArrayList<>();


//        2.查找最新的评论  封装到List<CommentVo>
        List<Comment> newsList=commentMapper.selectNewsCommentByBlogId(blogId);
        for (Comment comment:newsList){
            CommentVo commentVo=new CommentVo();
            BeanUtil.copyProperties(comment,commentVo);
            commentVos.add(commentVo);
        }


//        查找评论中对应的回复
        List<Reply> replyList = replyMapper.selectReplyListByCommentId(commentVos);

        for (CommentVo vo:commentVos){

//            将回复封装到CommentVo中
            List<Reply> replies=new ArrayList<>();
            for (Reply reply:replyList){
                if (vo.getCommentId().equals(reply.getCommentId())){
                    replies.add(reply);
                }
            }
            vo.setReplyList(replies);
        }

        return new AjaxResult().put("commentList",commentVos);
    }


    /**
     * 对blog进行评论
     * @param blogId
     * @return
     */
    @Override
    public AjaxResult addComment(Comment comment) {

        Long loginPersonId = securityUtils.getLoginPersonId();
//        统计互动数（点赞+收藏+评论）
        redisCache.setCacheHyperLogLog("statistics:interaction:"+loginPersonId, UUID.randomUUID());

//        comment.setCreateTime(new Date());
        comment.setPersonId(loginPersonId);
        int i=commentMapper.insertComment(comment);

        Comment c=commentMapper.selectCommentById(comment.getCommentId());
        CommentVo commentVo=new CommentVo();
        BeanUtil.copyProperties(c,commentVo);

        return AjaxResult.success().put("comment",commentVo);
    }
}
